package main

import (
	"bytes"
	"crypto/aes"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

// 定义一个结构体来表示请求体的JSON数据
type RequestBody struct {
	Version      string `json:"version"`
	MsgID        string `json:"msgid"`
	MinAppID     string `json:"minappid"`
	SystemTime   string `json:"systemtime"`
	ExpandParams string `json:"expandparams"`
	Token        string `json:"token"`
	Sign         string `json:"sign"`
}

// 定义一个结构体来表示响应的JSON数据
type ResponseBody struct {
	SystemTime  string `json:"systemTime"`
	ResultCode  string `json:"resultCode"`
	PhoneNumber string `json:"phoneNumber"`
}

// generateKey 创建一个32字节的密钥，使用SHA-256哈希生成。
func generateKey(passphrase string) []byte {
	hash := sha256.Sum256([]byte(passphrase))
	return hash[:]
}

// encrypt 使用AES-256在ECB模式下加密明文。
func encrypt(plaintext string, key []byte) (string, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	// 确保明文长度是块大小的倍数
	padding := aes.BlockSize - len(plaintext)%aes.BlockSize
	paddedText := append([]byte(plaintext), make([]byte, padding)...)

	ciphertext := make([]byte, len(paddedText))

	for bs, be := 0, block.BlockSize(); bs < len(paddedText); bs, be = bs+block.BlockSize(), be+block.BlockSize() {
		block.Encrypt(ciphertext[bs:be], paddedText[bs:be])
	}

	return hex.EncodeToString(ciphertext), nil
}

// decrypt 使用AES-256在ECB模式下解密密文。
func decrypt(ciphertext string, key []byte) (string, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	decodedCiphertext, err := hex.DecodeString(ciphertext)
	if err != nil {
		return "", err
	}

	plaintext := make([]byte, len(decodedCiphertext))

	for bs, be := 0, block.BlockSize(); bs < len(decodedCiphertext); bs, be = bs+block.BlockSize(), be+block.BlockSize() {
		block.Decrypt(plaintext[bs:be], decodedCiphertext[bs:be])
	}

	// 去除填充部分
	plaintext = bytes.TrimRight(plaintext, "\x00")

	return string(plaintext), nil
}

func handler(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodPost {
		// 读取请求体
		body, err := ioutil.ReadAll(r.Body)
		if err != nil {
			http.Error(w, "无法读取请求体", http.StatusBadRequest)
			return
		}
		defer r.Body.Close()

		// 解析JSON请求体
		var reqBody RequestBody
		err = json.Unmarshal(body, &reqBody)
		if err != nil {
			http.Error(w, "请求体格式错误", http.StatusBadRequest)
			return
		}

		// 打印解析后的数据
		fmt.Printf("Version: %s\n", reqBody.Version)
		fmt.Printf("MsgID: %s\n", reqBody.MsgID)
		fmt.Printf("MinAppID: %s\n", reqBody.MinAppID)
		fmt.Printf("SystemTime: %s\n", reqBody.SystemTime)
		fmt.Printf("ExpandParams: %s\n", reqBody.ExpandParams)
		fmt.Printf("Token: %s\n", reqBody.Token)
		fmt.Printf("Sign: %s\n", reqBody.Sign)

		phone := "17698817196"
		key := generateKey(reqBody.MinAppID + reqBody.SystemTime)
		encryptedPhone, err := encrypt(phone, key)
		if err != nil {
			log.Fatalf("加密时出错: %v", err)
		}
		fmt.Printf("加密后的手机号: %s\n", encryptedPhone)

		decryptedPhone, err := decrypt(encryptedPhone, key)
		fmt.Printf("本地解密的手机号: %s\n", decryptedPhone)

		// 准备返回的JSON数据
		response := ResponseBody{
			SystemTime:  reqBody.SystemTime,
			ResultCode:  "200",
			PhoneNumber: encryptedPhone,
		}

		// 将结构体转换为JSON格式
		responseData, err := json.Marshal(response)
		if err != nil {
			http.Error(w, "响应序列化错误", http.StatusInternalServerError)
			return
		}

		// 设置响应头和返回JSON数据
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		w.Write(responseData)
	} else {
		http.Error(w, "仅支持POST方法", http.StatusMethodNotAllowed)
	}
}

func main() {
	http.HandleFunc("/getPhone", handler)
	fmt.Println("服务器在33333端口监听...")
	log.Fatal(http.ListenAndServe(":33333", nil))
}
